package com.haoran.springadminserver;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

@Configuration
@EnableAutoConfiguration
@EnableAdminServer // 开启Admin
public class SpringAdminServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringAdminServerApplication.class, args);
    }
    /**
     * 开启服务端登录认证
     * 描述:展示登陆页面，需要登录才能访问
     *
     * zkh
     * 2019年9月24日 上午8:12:26
     */
    @Configuration
    public static class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
        private final String adminContextPath;

        public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
            this.adminContextPath = adminServerProperties.getContextPath();
        }

        /**
         * Admin服务端访问权限控制
         * 描述：跟被监控的客户端服务关系不大，我刚开始以为是给客户端配置的。。。
         */
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
            successHandler.setTargetUrlParameter("redirectTo");
            successHandler.setDefaultTargetUrl(adminContextPath + "/");

            http.authorizeRequests()
                    // 授予对所有静态资产和登录页的公共访问权限
                    .antMatchers(adminContextPath + "/assets/**").permitAll()
                    .antMatchers(adminContextPath + "/login").permitAll()
                    // 所有其他请求都必须经过身份验证
                    .anyRequest().authenticated().and()
                    // 配置登录和注销
                    .formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
                    .logout().logoutUrl(adminContextPath + "/logout").and()
                    // 启用HTTP基本支持。这是spring boot管理客户端注册所必需的
                    .httpBasic().and()
                    // 使用cookies启用csrf保护
                    .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                    .ignoringAntMatchers(
                            // 禁用crsf保护spring boot管理客户端用来注册的端点
                            adminContextPath + "/instances",
                            // 禁用执行器端点的CRSF保护
                            adminContextPath + "/actuator/**"
                    );
        }
    }
}
